package org.proxycine.gestsalles.web.beans;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.LineChartSeries;
import org.primefaces.model.chart.PieChartModel;
import org.proxycine.gestsalles.model.entities.Cinema;
import org.proxycine.gestsalles.model.entities.GenreFilm;
import org.proxycine.gestsalles.model.entities.RoleEmploye;
import org.proxycine.gestsalles.model.entities.TypeSpectateur;
import org.proxycine.gestsalles.services.CinemaService;
import org.proxycine.gestsalles.services.SeanceService;

@ManagedBean
@ViewScoped
public class TableauBordUnCinemaBean implements Serializable {

	/**
     * 
     */
	private static final long serialVersionUID = 1L;
	private LoginBean loginBean;
	private String loginGerant;
	private boolean isGerant;
	private boolean loginAcheteur;

	private List<Cinema> cinemas;
	private Cinema leCinema;

	private String type;
	private String critere;
	private Date dateDebut;
	private Date dateFin;
	private String chartTitle;
	
	
	private PieChartModel pieModel;
	private CartesianChartModel linearModel;
	
	private Map<GenreFilm, Integer> pieChartGenreFilmData;
	private Map<TypeSpectateur, Integer> pieChartTypeSpecData;
	private Map<TypeSpectateur, Map<java.sql.Date,Integer> > linearChartTypeSpecData;
	private Map<GenreFilm, Map<java.sql.Date, Integer> > linearChartGenreFilmData;
	private Map<java.sql.Date,Integer> linearChartAllData;


	public TableauBordUnCinemaBean() {

		
		chartTitle = "";
		type = "linechart";
		critere = "toutesEntrees";
		
		
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.WEEK_OF_MONTH, -2);
		// Date de début = il y a 2 semaines
		dateDebut = cal.getTime();
		
		cal.add(Calendar.WEEK_OF_MONTH, 1);
		// Date de fin = il y a 1 semaine
		dateFin = cal.getTime();
		
		
		FacesContext ctx = FacesContext.getCurrentInstance();
		loginAcheteur = false;
		loginBean = (LoginBean) ctx
				.getApplication()
				.getExpressionFactory()
				.createValueExpression(ctx.getELContext(), "#{loginBean}",
						LoginBean.class).getValue(ctx.getELContext());
		
		if(loginBean.getEmployeLogged().getRole().equals(RoleEmploye.Acheteur)
				|| loginBean.getEmployeLogged().getRole().equals(RoleEmploye.Programmeur)) {
			loginAcheteur = true;
		}
		else if(loginBean.getEmployeLogged().getRole().equals(RoleEmploye.Gerant)) {
			loginGerant = loginBean.getLogin();
			leCinema = CinemaService.getInstance().getCinemaOf(loginGerant);
		}
		
		cinemas = CinemaService.getInstance().getAllCinemas();

		leCinema = cinemas.get(0);
		
		linearChartAllData = SeanceService.getInstance().getAffluenceCinema(this.leCinema,
				getFormatedDate(dateDebut),
				getFormatedDate(dateFin));
		
		this.chartTitle = "Affluence totale";
		createLinearAllData();
		
		/*pieChartGenreFilmData = new HashMap<GenreFilm, Integer>();
		pieChartGenreFilmData.put(GenreFilm.Action, 10);
		pieChartGenreFilmData.put(GenreFilm.Comédie, 6);
		pieChartGenreFilmData.put(GenreFilm.Drame, 3);*/
		
		/*pieChartTypeSpecData = new HashMap<String, Integer>();
		pieChartTypeSpecData.put("étudiants", 40);
		pieChartTypeSpecData.put("normal", 80);
		pieChartTypeSpecData.put("séniors", 22);
		pieChartTypeSpecData.put("groupes", 8);*/
		
		/*linearChartTypeSpecData = new HashMap<String, Map<java.sql.Date,Integer> >();
		Map<java.sql.Date,Integer> t1 = new HashMap<java.sql.Date,Integer>();
		t1.put(java.sql.Date.valueOf("2012-01-01"), 400);
		t1.put(java.sql.Date.valueOf("2012-01-02"), 500);
		t1.put(java.sql.Date.valueOf("2012-01-03"), 300);
		t1.put(java.sql.Date.valueOf("2012-01-04"), 800);
		linearChartTypeSpecData.put("étudiants", t1);
		Map<java.sql.Date,Integer> t2 = new HashMap<java.sql.Date,Integer>();
		t2.put(java.sql.Date.valueOf("2012-01-01"), 600);
		t2.put(java.sql.Date.valueOf("2012-01-02"), 900);
		t2.put(java.sql.Date.valueOf("2012-01-03"), 500);
		t2.put(java.sql.Date.valueOf("2012-01-04"), 200);
		linearChartTypeSpecData.put("normal", t2);*/
		
		/*linearChartGenreFilmData = new HashMap<GenreFilm, Map<java.sql.Date,Integer> >();
		Map<java.sql.Date,Integer> t3 = new HashMap<java.sql.Date,Integer>();
		t3.put(java.sql.Date.valueOf("2012-01-01"), 400);
		t3.put(java.sql.Date.valueOf("2012-01-02"), 500);
		t3.put(java.sql.Date.valueOf("2012-01-03"), 300);
		t3.put(java.sql.Date.valueOf("2012-01-04"), 800);
		linearChartGenreFilmData.put(GenreFilm.Action, t3);
		Map<java.sql.Date,Integer> t4 = new HashMap<java.sql.Date,Integer>();
		t4.put(java.sql.Date.valueOf("2012-01-01"), 600);
		t4.put(java.sql.Date.valueOf("2012-01-02"), 900);
		t4.put(java.sql.Date.valueOf("2012-01-03"), 500);
		t4.put(java.sql.Date.valueOf("2012-01-04"), 200);
		linearChartGenreFilmData.put(GenreFilm.Comédie, t4);*/
		
		
		/*linearChartAllData = new HashMap<java.sql.Date,Integer>();
		linearChartAllData.put(java.sql.Date.valueOf("2012-01-01"), 400);
		linearChartAllData.put(java.sql.Date.valueOf("2012-01-02"), 500);
		linearChartAllData.put(java.sql.Date.valueOf("2012-01-03"), 300);
		linearChartAllData.put(java.sql.Date.valueOf("2012-01-04"), 800);
		linearChartAllData.put(java.sql.Date.valueOf("2012-01-05"), 600);
		linearChartAllData.put(java.sql.Date.valueOf("2012-01-06"), 900);
		linearChartAllData.put(java.sql.Date.valueOf("2012-01-07"), 500);
		linearChartAllData.put(java.sql.Date.valueOf("2012-01-08"), 200);*/
		
	}
	
	public void valide() {
		
		System.out.println("type : " + type);
		System.out.println("critere : " + critere);
		System.out.println("dateDebut : " + dateDebut.toString());
		
		if (dateFin.before(dateDebut)) {
			Date tempDate = dateDebut;
			dateDebut = dateFin;
			dateFin = tempDate;
		}
		
		System.out.println("dateFin : " + dateFin.toString());
		
		
		
		// Camemberts
		if (type.equals("piechart") && critere.equals("genreFilm")) {
			
			pieChartGenreFilmData = SeanceService.getInstance().getPartAffluenceCinemaParGenre(this.leCinema,
					getFormatedDate(dateDebut),
					getFormatedDate(dateFin));
			
			this.chartTitle = "% affluence par genre de films";
			createPieModelGenreFilm();
		} else if (type.equals("piechart") && critere.equals("typeSpectateur")) {
			
			pieChartTypeSpecData = SeanceService.getInstance().getPartAffluenceCinemaParCategorieSpec(this.leCinema,
					getFormatedDate(dateDebut),
					getFormatedDate(dateFin));
			
			this.chartTitle = "% affluence par type de spectateurs";
			createPieModelTypeSpec();
		} 
		
		// Courbes
		else if (type.equals("linechart") && critere.equals("genreFilm")) {
			
			 linearChartGenreFilmData = SeanceService.getInstance().getAffluenceCinemaParGenre(this.leCinema,
						getFormatedDate(dateDebut),
						getFormatedDate(dateFin));
			
			this.chartTitle = "Affluence par genre de films";
			createLinearModelGenreFilm();
			
		} else if (type.equals("linechart") && critere.equals("typeSpectateur")) {

			linearChartTypeSpecData = SeanceService.getInstance().getAffluenceCinemaParCategorieSpec(this.leCinema,
					getFormatedDate(dateDebut),
					getFormatedDate(dateFin));
			
			this.chartTitle = "Affluence par type de spectateurs";
			createLinearModelTypeSpec();
		} 
		
		// Si on sélectionne ce critère, le type de graph n'a pas d'importance, ça sera forcément
		// un linechart
		else if (critere.equals("toutesEntrees")) {	
			type = "linechart";
						
			linearChartAllData = SeanceService.getInstance().getAffluenceCinema(this.leCinema,
					getFormatedDate(dateDebut),
					getFormatedDate(dateFin));
			
			this.chartTitle = "Affluence totale";
			createLinearAllData();
		}
	}
	
	public String getFormatedDate(java.util.Date d) {
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateFormat.format(d);
	}

	public PieChartModel getPieModel() {  
        return pieModel;  
    }  
  
    private void createPieModelGenreFilm() {  
        pieModel = new PieChartModel();  
  
        Set<GenreFilm> keySet = pieChartGenreFilmData.keySet();
        for(GenreFilm genre : keySet) {
        	pieModel.set("" + genre, pieChartGenreFilmData.get(genre));

        }        
    }
    
    private void createPieModelTypeSpec() {  
        pieModel = new PieChartModel();  
        
        Set<TypeSpectateur> keySet = pieChartTypeSpecData.keySet();
        for(TypeSpectateur type: keySet) {
        	pieModel.set(type.name(), pieChartTypeSpecData.get(type));
        }        
    }
    
    
    private void createLinearModelGenreFilm() {  
    	
    	linearModel = new CartesianChartModel();
    	Set<GenreFilm> keySet = linearChartGenreFilmData.keySet();
    	for(GenreFilm genre : keySet) {
    		LineChartSeries serie = new LineChartSeries();  
            serie.setLabel("" + genre);
            
            Set<java.sql.Date> keySetData = linearChartGenreFilmData.get(genre).keySet();
            for(java.sql.Date date : keySetData) {
            	serie.set(date,linearChartGenreFilmData.get(genre).get(date));
            }
            linearModel.addSeries(serie);
    	}  
    } 
    
	private void createLinearModelTypeSpec() {  
    	
		linearModel = new CartesianChartModel();
    	Set<TypeSpectateur> keySet = linearChartTypeSpecData.keySet();
    	for(TypeSpectateur type : keySet) {
    		LineChartSeries serie = new LineChartSeries();  
            serie.setLabel(type.name());
            
            Set<java.sql.Date> keySetData = linearChartTypeSpecData.get(type).keySet();
            for(java.sql.Date date : keySetData) {
            	serie.set(date,linearChartTypeSpecData.get(type).get(date));
            }
            linearModel.addSeries(serie);
    	}  
    } 
	
	private void createLinearAllData() {  
		
		linearModel = new CartesianChartModel();
		LineChartSeries serie = new LineChartSeries();  
        serie.setLabel("affluence totale");
        
        Set<java.sql.Date> keySetData = linearChartAllData.keySet();
        for(java.sql.Date date : keySetData) {
        	serie.set(date,linearChartAllData.get(date));
        }
        
        linearModel.addSeries(serie);
    } 
	

	public Cinema getLeCinema() {
		return leCinema;
	}

	public void setLeCinema(Cinema leCinema) {
		this.leCinema = leCinema;
	}
	
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getCritere() {
		return critere;
	}

	public void setCritere(String critere) {
		this.critere = critere;
	}

	public Date getDateDebut() {
		return dateDebut;
	}

	public void setDateDebut(Date dateDebut) {
		this.dateDebut = dateDebut;
	}

	public Date getDateFin() {
		return dateFin;
	}

	public void setDateFin(Date dateFin) {
		this.dateFin = dateFin;
	}

	public String getChartTitle() {
		return chartTitle;
	}

	public CartesianChartModel getLinearModel() {
		return linearModel;
	}

	public Map<GenreFilm, Integer> getPieChartGenreFilmData() {
		return pieChartGenreFilmData;
	}

	public void setPieChartGenreFilmData(Map<GenreFilm, Integer> pieChartGenreFilmData) {
		this.pieChartGenreFilmData = pieChartGenreFilmData;
	}

	public Map<TypeSpectateur, Integer> getPieChartTypeSpecData() {
		return pieChartTypeSpecData;
	}

	public void setPieChartTypeSpecData(Map<TypeSpectateur, Integer> pieChartTypeSpecData) {
		this.pieChartTypeSpecData = pieChartTypeSpecData;
	}

	public Map<TypeSpectateur, Map<java.sql.Date,Integer> > getLinearChartTypeSpecData() {
		return linearChartTypeSpecData;
	}

	public void setLinearChartTypeSpecData(Map<TypeSpectateur, Map<java.sql.Date,Integer> > linearChartTypeSpecData) {
		this.linearChartTypeSpecData = linearChartTypeSpecData;
	}

	public Map<GenreFilm, Map<java.sql.Date,Integer> > getLinearChartGenreFilmData() {
		return linearChartGenreFilmData;
	}

	public void setLinearChartGenreFilmData(Map<GenreFilm, Map<java.sql.Date,Integer> > linearChartGenreFilmData) {
		this.linearChartGenreFilmData = linearChartGenreFilmData;
	}

	public Map<java.sql.Date,Integer> getLinearChartAllData() {
		return linearChartAllData;
	}

	public void setLinearChartAllData(Map<java.sql.Date,Integer> linearChartAllData) {
		this.linearChartAllData = linearChartAllData;
	}

	public boolean isGerant() {
		return isGerant;
	}

	public void setGerant(boolean isGerant) {
		this.isGerant = isGerant;
	}

	public List<Cinema> getCinemas() {
		return cinemas;
	}

	public void setCinemas(List<Cinema> cinemas) {
		this.cinemas = cinemas;
	}

	public boolean isLoginAcheteur() {
		return loginAcheteur;
	}

	public void setLoginAcheteur(boolean loginAcheteur) {
		this.loginAcheteur = loginAcheteur;
	}


}